#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
校准数据验证界面
基于AttenuatorCompensator类的校准数据验证界面设计
"""

import sys
import json
import os
import logging
import serial.tools.list_ports
from typing import Optional, Dict, List
from datetime import datetime

from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from PyQt5.QtGui import *

from attenuator_compensator import AttenuatorCompensator
from calibration_data_reader import CalibrationDataReader
from digital_attenuator import DigitalAttenuator
from widgets.widgets import InstrumentInfoWidget
from instruments.sg import KeysightSignalGenerator, RSSignalGenerator
from instruments.sa import KeysightSignalAnalyzer, RSSignalAnalyzer
from verification_engine import VerificationEngine, ReportGenerator


class VerificationTableModel(QAbstractTableModel):
    """验证测试表格数据模型"""
    
    def __init__(self):
        super().__init__()
        self.test_data = []  # 测试数据列表
        self.headers = [
            "序号", "频率(MHz)", "目标衰减(dB)", "理论补偿值(dB)",
            "实际设置值(dB)", "测量值(dBm)", "实际衰减(dB)", 
            "误差(dB)", "状态"
        ]
    
    def rowCount(self, parent=QModelIndex()):
        return len(self.test_data)
    
    def columnCount(self, parent=QModelIndex()):
        return len(self.headers)
    
    def data(self, index, role=Qt.DisplayRole):
        if not index.isValid():
            return None
            
        row = index.row()
        col = index.column()
        
        if row >= len(self.test_data):
            return None
            
        item = self.test_data[row]
        
        if role == Qt.DisplayRole:
            if col == 0:  # 序号
                return row + 1
            elif col == 1:  # 频率
                return f"{item.get('frequency', 0):.1f}"
            elif col == 2:  # 目标衰减
                return f"{item.get('target_attenuation', 0):.2f}"
            elif col == 3:  # 理论补偿值
                return f"{item.get('theoretical_compensation', 0):.2f}"
            elif col == 4:  # 实际设置值
                return f"{item.get('actual_setting', 0):.2f}"
            elif col == 5:  # 测量值
                return f"{item.get('measured_power', 0):.2f}"
            elif col == 6:  # 实际衰减
                return f"{item.get('actual_attenuation', 0):.2f}"
            elif col == 7:  # 误差
                return f"{item.get('error', 0):.2f}"
            elif col == 8:  # 状态
                return item.get('status', '待测试')
        
        elif role == Qt.BackgroundRole:
            status = item.get('status', '待测试')
            if status == '完成':
                return QColor(200, 255, 200)  # 淡绿色
            elif status == '测试中':
                return QColor(255, 255, 200)  # 淡黄色
            elif status == '失败':
                return QColor(255, 200, 200)  # 淡红色
                
        return None
    
    def headerData(self, section, orientation, role=Qt.DisplayRole):
        if orientation == Qt.Horizontal and role == Qt.DisplayRole:
            return self.headers[section]
        return None
    
    def add_test_item(self, frequency: float, target_attenuation: float):
        """添加测试项"""
        self.beginInsertRows(QModelIndex(), len(self.test_data), len(self.test_data))
        self.test_data.append({
            'frequency': frequency,
            'target_attenuation': target_attenuation,
            'theoretical_compensation': 0.0,
            'actual_setting': 0.0,
            'measured_power': 0.0,
            'actual_attenuation': 0.0,
            'error': 0.0,
            'status': '待测试'
        })
        self.endInsertRows()
    
    def update_test_result(self, index: int, result: dict):
        """更新测试结果"""
        if 0 <= index < len(self.test_data):
            self.test_data[index].update(result)
            # 发出数据改变信号
            start_idx = self.createIndex(index, 0)
            end_idx = self.createIndex(index, len(self.headers) - 1)
            self.dataChanged.emit(start_idx, end_idx)
    
    def clear_all(self):
        """清除所有数据"""
        self.beginResetModel()
        self.test_data.clear()
        self.endResetModel()
    
    def export_to_csv(self, file_path: str):
        """导出数据到CSV文件"""
        import csv
        with open(file_path, 'w', newline='', encoding='utf-8') as csvfile:
            writer = csv.writer(csvfile)
            # 写入表头
            writer.writerow(self.headers)
            # 写入数据
            for i, item in enumerate(self.test_data):
                row = [
                    i + 1,
                    item.get('frequency', 0),
                    item.get('target_attenuation', 0),
                    item.get('theoretical_compensation', 0),
                    item.get('actual_setting', 0),
                    item.get('measured_power', 0),
                    item.get('actual_attenuation', 0),
                    item.get('error', 0),
                    item.get('status', '待测试')
                ]
                writer.writerow(row)


class LossDataReader:
    """线损数据读取器"""
    
    def __init__(self, loss_file_path: str = ""):
        self.loss_file_path = loss_file_path
        self.loss_data = {}
        if loss_file_path:
            self.load_loss_data()
    
    def load_loss_data(self, file_path: str = None) -> bool:
        """加载线损数据文件"""
        if file_path:
            self.loss_file_path = file_path
            
        if not self.loss_file_path or not os.path.exists(self.loss_file_path):
            return False
            
        try:
            with open(self.loss_file_path, 'r', encoding='utf-8') as f:
                self.loss_data = json.load(f)
            return True
        except Exception as e:
            logging.error(f"加载线损数据失败: {e}")
            return False
    
    def get_loss_at_frequency(self, frequency: float) -> float:
        """获取指定频率的线损值"""
        if not self.loss_data:
            return 0.0
            
        # 查找最接近的频率点
        frequencies = [float(freq) for freq in self.loss_data.keys()]
        if not frequencies:
            return 0.0
            
        closest_freq = min(frequencies, key=lambda x: abs(x - frequency))
        return float(self.loss_data.get(str(closest_freq), 0.0))


class VerificationWindow(QMainWindow):
    """校准数据验证主界面"""
    
    def __init__(self):
        super().__init__()
        self.setWindowTitle("衰减器校准数据验证界面")
        self.setGeometry(100, 100, 1400, 900)
        
        # 核心组件
        self.compensator = None
        self.calibration_reader = None
        self.loss_reader = LossDataReader()
        self.attenuator = None
        self.sg = None
        self.sa = None
        
        # 验证引擎
        self.verification_engine = None
        
        # 数据模型
        self.table_model = VerificationTableModel()
        
        # 初始化界面
        self.init_ui()
        self.refresh_serial_ports()
        
        # 状态栏
        self.status_bar = QStatusBar()
        self.setStatusBar(self.status_bar)
        self.status_bar.showMessage('准备就绪')
    
    def init_ui(self):
        """初始化用户界面"""
        central_widget = QWidget()
        self.setCentralWidget(central_widget)
        
        # 主布局
        main_layout = QHBoxLayout(central_widget)
        
        # 左侧控制区域
        control_widget = self.create_control_panel()
        main_layout.addWidget(control_widget, 1)
        
        # 右侧显示区域
        display_widget = self.create_display_panel()
        main_layout.addWidget(display_widget, 2)
    
    def create_control_panel(self) -> QWidget:
        """创建左侧控制面板"""
        control_widget = QWidget()
        layout = QVBoxLayout(control_widget)
        
        # 文件加载区
        file_group = self.create_file_group()
        layout.addWidget(file_group)
        
        # 仪器连接区
        instrument_group = self.create_instrument_group()
        layout.addWidget(instrument_group)
        
        # 验证参数设置区
        param_group = self.create_parameter_group()
        layout.addWidget(param_group)
        
        # 控制按钮区
        button_group = self.create_button_group()
        layout.addWidget(button_group)
        
        # 添加弹性空间
        layout.addStretch()
        
        return control_widget
    
    def create_file_group(self) -> QGroupBox:
        """创建文件加载组"""
        group = QGroupBox("文件加载")
        layout = QFormLayout(group)
        
        # 校准数据文件
        self.cal_file_edit = QLineEdit()
        cal_file_btn = QPushButton("浏览...")
        cal_file_btn.clicked.connect(self.browse_calibration_file)
        cal_layout = QHBoxLayout()
        cal_layout.addWidget(self.cal_file_edit)
        cal_layout.addWidget(cal_file_btn)
        layout.addRow("校准数据文件:", cal_layout)
        
        # 线损数据文件
        self.loss_file_edit = QLineEdit()
        self.loss_file_edit.setText(r"E:/PycharmProjects/其他项目集/可调衰减器的校准程序/美国Meta 一根线 线损.json")
        loss_file_btn = QPushButton("浏览...")
        loss_file_btn.clicked.connect(self.browse_loss_file)
        loss_layout = QHBoxLayout()
        loss_layout.addWidget(self.loss_file_edit)
        loss_layout.addWidget(loss_file_btn)
        layout.addRow("线损数据文件:", loss_layout)
        
        return group
    
    def create_instrument_group(self) -> QGroupBox:
        """创建仪器连接组"""
        group = QGroupBox("仪器连接")
        layout = QVBoxLayout(group)
        
        # 信号源
        self.sg_widget = InstrumentInfoWidget('SG', ['Keysight', "R&S"])
        layout.addWidget(self.sg_widget)
        
        # 频谱仪
        self.sa_widget = InstrumentInfoWidget('SA', ['Keysight', "R&S"])
        layout.addWidget(self.sa_widget)

        self.sa_widget.vias_address_editer.setText('TCPIP0::192.168.8.201::inst0::INSTR')
        self.sg_widget.vias_address_editer.setText('TCPIP0::192.168.1.102::inst0::INSTR')
        
        # 衰减器串口设置
        att_layout = QHBoxLayout()
        att_layout.addWidget(QLabel("衰减器串口:"))
        self.port_combo = QComboBox()
        att_layout.addWidget(self.port_combo)
        refresh_btn = QPushButton("刷新")
        refresh_btn.clicked.connect(self.refresh_serial_ports)
        att_layout.addWidget(refresh_btn)
        layout.addLayout(att_layout)
        
        # 连接按钮
        connect_layout = QHBoxLayout()
        self.connect_instruments_btn = QPushButton("连接所有仪器")
        self.connect_instruments_btn.clicked.connect(self.connect_instruments)
        connect_layout.addWidget(self.connect_instruments_btn)
        
        self.disconnect_instruments_btn = QPushButton("断开所有仪器")
        self.disconnect_instruments_btn.clicked.connect(self.disconnect_instruments)
        self.disconnect_instruments_btn.setEnabled(False)
        connect_layout.addWidget(self.disconnect_instruments_btn)
        
        layout.addLayout(connect_layout)
        
        return group
    
    def create_parameter_group(self) -> QGroupBox:
        """创建验证参数设置组"""
        group = QGroupBox("验证参数设置")
        layout = QFormLayout(group)
        
        # 单点测试参数
        single_layout = QHBoxLayout()
        self.single_freq_spin = QDoubleSpinBox()
        self.single_freq_spin.setRange(10, 6000)
        self.single_freq_spin.setValue(2412)
        self.single_freq_spin.setSuffix(" MHz")
        single_layout.addWidget(self.single_freq_spin)
        
        self.single_att_spin = QDoubleSpinBox()
        self.single_att_spin.setRange(0, 90)
        self.single_att_spin.setValue(20)
        self.single_att_spin.setSuffix(" dB")
        single_layout.addWidget(self.single_att_spin)
        
        add_single_btn = QPushButton("添加测试点")
        add_single_btn.clicked.connect(self.add_single_test_point)
        single_layout.addWidget(add_single_btn)
        
        layout.addRow("单点测试:", single_layout)
        
        # 批量测试参数
        batch_group = QGroupBox("批量测试参数")
        batch_layout = QFormLayout(batch_group)
        
        # 频率范围
        freq_range_layout = QHBoxLayout()
        self.start_freq_spin = QDoubleSpinBox()
        self.start_freq_spin.setRange(10, 6000)
        self.start_freq_spin.setValue(1000)
        self.start_freq_spin.setSuffix(" MHz")
        freq_range_layout.addWidget(QLabel("起始:"))
        freq_range_layout.addWidget(self.start_freq_spin)
        
        self.stop_freq_spin = QDoubleSpinBox()
        self.stop_freq_spin.setRange(10, 6000)
        self.stop_freq_spin.setValue(3000)
        self.stop_freq_spin.setSuffix(" MHz")
        freq_range_layout.addWidget(QLabel("结束:"))
        freq_range_layout.addWidget(self.stop_freq_spin)
        
        self.step_freq_spin = QDoubleSpinBox()
        self.step_freq_spin.setRange(1, 1000)
        self.step_freq_spin.setValue(500)
        self.step_freq_spin.setSuffix(" MHz")
        freq_range_layout.addWidget(QLabel("步进:"))
        freq_range_layout.addWidget(self.step_freq_spin)
        
        batch_layout.addRow("频率范围:", freq_range_layout)
        
        # 衰减范围
        att_range_layout = QHBoxLayout()
        self.start_att_spin = QDoubleSpinBox()
        self.start_att_spin.setRange(0, 90)
        self.start_att_spin.setValue(10)
        self.start_att_spin.setSuffix(" dB")
        att_range_layout.addWidget(QLabel("起始:"))
        att_range_layout.addWidget(self.start_att_spin)
        
        self.stop_att_spin = QDoubleSpinBox()
        self.stop_att_spin.setRange(0, 90)
        self.stop_att_spin.setValue(50)
        self.stop_att_spin.setSuffix(" dB")
        att_range_layout.addWidget(QLabel("结束:"))
        att_range_layout.addWidget(self.stop_att_spin)
        
        self.step_att_spin = QDoubleSpinBox()
        self.step_att_spin.setRange(1, 20)
        self.step_att_spin.setValue(10)
        self.step_att_spin.setSuffix(" dB")
        att_range_layout.addWidget(QLabel("步进:"))
        att_range_layout.addWidget(self.step_att_spin)
        
        batch_layout.addRow("衰减范围:", att_range_layout)
        
        # 生成批量测试序列按钮
        generate_btn = QPushButton("生成测试序列")
        generate_btn.clicked.connect(self.generate_test_sequence)
        batch_layout.addRow("", generate_btn)
        
        layout.addRow("", batch_group)
        
        # 测试设置
        self.repeat_spin = QSpinBox()
        self.repeat_spin.setRange(1, 10)
        self.repeat_spin.setValue(1)
        layout.addRow("重复次数:", self.repeat_spin)
        
        return group
    
    def create_button_group(self) -> QGroupBox:
        """创建控制按钮组"""
        group = QGroupBox("验证控制")
        layout = QVBoxLayout(group)
        
        # 第一行按钮
        row1_layout = QHBoxLayout()
        
        self.start_btn = QPushButton("开始验证")
        self.start_btn.clicked.connect(self.start_verification)
        self.start_btn.setEnabled(False)
        row1_layout.addWidget(self.start_btn)
        
        self.pause_btn = QPushButton("暂停")
        self.pause_btn.clicked.connect(self.pause_verification)
        self.pause_btn.setEnabled(False)
        row1_layout.addWidget(self.pause_btn)
        
        self.stop_btn = QPushButton("停止")
        self.stop_btn.clicked.connect(self.stop_verification)
        self.stop_btn.setEnabled(False)
        row1_layout.addWidget(self.stop_btn)
        
        layout.addLayout(row1_layout)
        
        # 第二行按钮
        row2_layout = QHBoxLayout()
        
        clear_btn = QPushButton("清除数据")
        clear_btn.clicked.connect(self.clear_test_data)
        row2_layout.addWidget(clear_btn)
        
        export_btn = QPushButton("导出报告")
        export_btn.clicked.connect(self.export_report)
        row2_layout.addWidget(export_btn)
        
        layout.addLayout(row2_layout)
        
        return group
    
    def create_display_panel(self) -> QWidget:
        """创建右侧显示面板"""
        display_widget = QWidget()
        layout = QVBoxLayout(display_widget)
        
        # 测试结果表格
        self.test_table = QTableView()
        self.test_table.setModel(self.table_model)
        self.test_table.setAlternatingRowColors(True)
        self.test_table.setSelectionBehavior(QAbstractItemView.SelectRows)
        
        # 设置列宽
        header = self.test_table.horizontalHeader()
        header.setStretchLastSection(True)
        for i in range(len(self.table_model.headers) - 1):
            header.setSectionResizeMode(i, QHeaderView.ResizeToContents)
        
        layout.addWidget(QLabel("验证测试结果:"))
        layout.addWidget(self.test_table)
        
        # 进度条
        self.progress_bar = QProgressBar()
        self.progress_bar.setVisible(False)
        layout.addWidget(self.progress_bar)
        
        # 日志输出
        self.log_text = QPlainTextEdit()
        self.log_text.setMaximumHeight(200)
        layout.addWidget(QLabel("验证日志:"))
        layout.addWidget(self.log_text)
        
        return display_widget
    
    def refresh_serial_ports(self):
        """刷新串口列表"""
        self.port_combo.clear()
        ports = serial.tools.list_ports.comports()
        for port in ports:
            self.port_combo.addItem(f"{port.device} - {port.description}")
    
    def browse_calibration_file(self):
        """浏览校准数据文件"""
        file_path, _ = QFileDialog.getOpenFileName(
            self, "选择校准数据文件", "", "JSON files (*.json)")
        if file_path:
            self.cal_file_edit.setText(file_path)
            self.load_calibration_data(file_path)
    
    def browse_loss_file(self):
        """浏览线损数据文件"""
        file_path, _ = QFileDialog.getOpenFileName(
            self, "选择线损数据文件", "", "JSON files (*.json)")
        if file_path:
            self.loss_file_edit.setText(file_path)
            self.load_loss_data(file_path)
    
    def load_calibration_data(self, file_path: str) -> bool:
        """加载校准数据文件"""
        try:
            self.calibration_reader = CalibrationDataReader(file_path)
            if self.calibration_reader.is_data_available():
                self.compensator = AttenuatorCompensator(self.calibration_reader)
                self.log_message("✅ 校准数据加载成功")
                self.update_verification_enabled()
                return True
            else:
                self.log_message("❌ 校准数据加载失败")
                return False
        except Exception as e:
            self.log_message(f"❌ 校准数据加载异常: {str(e)}")
            return False
    
    def load_loss_data(self, file_path: str) -> bool:
        """加载线损数据文件"""
        if self.loss_reader.load_loss_data(file_path):
            self.log_message("✅ 线损数据加载成功")
            return True
        else:
            self.log_message("❌ 线损数据加载失败")
            return False
    
    def connect_instruments(self):
        """连接所有仪器"""
        try:
            # 连接信号源
            sg_model = self.sg_widget.instrument_model_combobox.currentText()
            sg_address = self.sg_widget.vias_address_editer.text()
            if sg_model == 'Keysight':
                self.sg = KeysightSignalGenerator(sg_address)
            else:
                self.sg = RSSignalGenerator(sg_address)
            
            if not self.sg.connect():
                raise Exception("信号源连接失败")
            
            # 连接频谱仪
            sa_model = self.sa_widget.instrument_model_combobox.currentText()
            sa_address = self.sa_widget.vias_address_editer.text()
            if sa_model == 'Keysight':
                self.sa = KeysightSignalAnalyzer(sa_address)
            else:
                self.sa = RSSignalAnalyzer(sa_address)
            
            if not self.sa.connect():
                raise Exception("频谱仪连接失败")
            
            # 连接衰减器
            port_text = self.port_combo.currentText()
            if port_text:
                port = port_text.split(' - ')[0]
                self.attenuator = DigitalAttenuator(port)
                self.attenuator.connect()
                
            self.log_message("✅ 所有仪器连接成功")
            self.connect_instruments_btn.setEnabled(False)
            self.disconnect_instruments_btn.setEnabled(True)
            self.update_verification_enabled()
            
        except Exception as e:
            self.log_message(f"❌ 仪器连接失败: {str(e)}")
    
    def disconnect_instruments(self):
        """断开所有仪器连接"""
        try:
            if self.sg:
                self.sg.disconnect()
                self.sg = None
            if self.sa:
                self.sa.disconnect()
                self.sa = None
            if self.attenuator:
                self.attenuator.disconnect()
                self.attenuator = None
                
            self.log_message("✅ 所有仪器断开连接")
            self.connect_instruments_btn.setEnabled(True)
            self.disconnect_instruments_btn.setEnabled(False)
            self.update_verification_enabled()
            
        except Exception as e:
            self.log_message(f"❌ 仪器断开失败: {str(e)}")
    
    def update_verification_enabled(self):
        """更新验证按钮状态"""
        can_verify = (self.compensator is not None and 
                     self.sg is not None and 
                     self.sa is not None and 
                     self.attenuator is not None)
        self.start_btn.setEnabled(can_verify)
    
    def add_single_test_point(self):
        """添加单个测试点"""
        frequency = self.single_freq_spin.value()
        target_attenuation = self.single_att_spin.value()
        self.table_model.add_test_item(frequency, target_attenuation)
        self.log_message(f"添加测试点: {frequency} MHz, {target_attenuation} dB")
    
    def generate_test_sequence(self):
        """生成批量测试序列"""
        start_freq = self.start_freq_spin.value()
        stop_freq = self.stop_freq_spin.value()
        step_freq = self.step_freq_spin.value()
        
        start_att = self.start_att_spin.value()
        stop_att = self.stop_att_spin.value()
        step_att = self.step_att_spin.value()
        
        count = 0
        freq = start_freq
        while freq <= stop_freq:
            att = start_att
            while att <= stop_att:
                self.table_model.add_test_item(freq, att)
                count += 1
                att += step_att
            freq += step_freq
        
        self.log_message(f"生成 {count} 个测试点")
    
    def clear_test_data(self):
        """清除测试数据"""
        self.table_model.clear_all()
        self.log_message("清除所有测试数据")
    
    def start_verification(self):
        """开始验证"""
        if not self.table_model.test_data:
            QMessageBox.warning(self, "警告", "请先添加测试点")
            return
        
        self.log_message("🚀 开始验证流程...")
        self.start_btn.setEnabled(False)
        self.pause_btn.setEnabled(True)
        self.stop_btn.setEnabled(True)
        self.progress_bar.setVisible(True)
        self.progress_bar.setMaximum(len(self.table_model.test_data))
        self.progress_bar.setValue(0)
        
        # 创建验证引擎
        instruments = {
            'sg': self.sg,
            'sa': self.sa,
            'attenuator': self.attenuator
        }
        
        repeat_count = self.repeat_spin.value()
        
        self.verification_engine = VerificationEngine(
            self.compensator,
            instruments,
            self.table_model.test_data,
            self.loss_reader,
            repeat_count
        )
        
        # 连接信号
        self.verification_engine.progress_updated.connect(self.progress_bar.setValue)
        self.verification_engine.test_completed.connect(self.on_test_completed)
        self.verification_engine.verification_finished.connect(self.on_verification_finished)
        self.verification_engine.log_message.connect(self.log_message)
        
        # 启动验证引擎
        self.verification_engine.start()
    
    def pause_verification(self):
        """暂停验证"""
        if self.verification_engine:
            if self.verification_engine.is_paused:
                self.verification_engine.resume()
                self.pause_btn.setText("暂停")
            else:
                self.verification_engine.pause()
                self.pause_btn.setText("继续")
    
    def stop_verification(self):
        """停止验证"""
        if self.verification_engine:
            self.verification_engine.stop()
        
        self.start_btn.setEnabled(True)
        self.pause_btn.setEnabled(False)
        self.pause_btn.setText("暂停")
        self.stop_btn.setEnabled(False)
        self.progress_bar.setVisible(False)
    
    def export_report(self):
        """导出验证报告"""
        if not self.table_model.test_data:
            QMessageBox.information(self, "提示", "没有数据可导出")
            return
        
        # 选择文件类型
        file_dialog = QFileDialog(self)
        file_dialog.setAcceptMode(QFileDialog.AcceptSave)
        file_dialog.setNameFilters([
            "CSV 文件 (*.csv)",
            "HTML 报告 (*.html)"
        ])
        file_dialog.setDefaultSuffix("csv")
        
        default_name = f"verification_report_{datetime.now().strftime('%Y%m%d_%H%M%S')}"
        file_dialog.selectFile(default_name)
        
        if file_dialog.exec_() == QFileDialog.Accepted:
            file_path = file_dialog.selectedFiles()[0]
            file_filter = file_dialog.selectedNameFilter()
            
            try:
                if "CSV" in file_filter:
                    self.table_model.export_to_csv(file_path)
                elif "HTML" in file_filter:
                    # 生成HTML报告
                    report_generator = ReportGenerator(self.table_model.test_data)
                    statistics = report_generator.generate_summary_statistics()
                    report_generator.generate_html_report(file_path, statistics)
                
                self.log_message(f"✅ 报告导出成功: {file_path}")
                
                # 显示统计信息
                if "HTML" in file_filter:
                    stats_msg = (f"统计摘要: 成功率={statistics.get('completion_rate', 0):.1f}%, "
                               f"平均误差={statistics.get('mean_absolute_error', 0):.3f}dB")
                    self.log_message(stats_msg)
                    
            except Exception as e:
                self.log_message(f"❌ 报告导出失败: {str(e)}")
    
    def on_test_completed(self, test_index: int, result: dict):
        """单个测试完成回调"""
        self.table_model.update_test_result(test_index, result)
    
    def on_verification_finished(self, success: bool):
        """验证完成回调"""
        self.start_btn.setEnabled(True)
        self.pause_btn.setEnabled(False)
        self.pause_btn.setText("暂停")
        self.stop_btn.setEnabled(False)
        self.progress_bar.setVisible(False)
        
        if success:
            self.log_message("✅ 验证流程完成！")
            
            # 显示统计信息
            report_generator = ReportGenerator(self.table_model.test_data)
            statistics = report_generator.generate_summary_statistics()
            
            stats_msg = (f"统计结果: 成功={statistics.get('successful_tests', 0)}, "
                        f"失败={statistics.get('failed_tests', 0)}, "
                        f"平均误差={statistics.get('mean_absolute_error', 0):.3f}dB")
            self.log_message(stats_msg)
            
            # 显示完成对话框
            QMessageBox.information(
                self, "验证完成", 
                f"验证流程已完成！\n\n{stats_msg}"
            )
        else:
            self.log_message("⚠️ 验证流程未正常结束")
    
    def log_message(self, message: str):
        """添加日志消息"""
        timestamp = datetime.now().strftime("%H:%M:%S")
        log_msg = f"[{timestamp}] {message}"
        self.log_text.appendPlainText(log_msg)
        self.status_bar.showMessage(message)


def main():
    """主程序入口"""
    app = QApplication(sys.argv)
    
    # 设置应用图标和样式
    app.setApplicationName("衰减器校准数据验证")
    app.setApplicationVersion("1.0")
    
    # 创建主窗口
    window = VerificationWindow()
    window.show()
    
    sys.exit(app.exec_())


if __name__ == "__main__":
    main()